package com.hdu;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;


@Slf4j
public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        testEnhanceFutureTask();
    }


    public static void testTaskFuture() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            log.info("开始执行任务.....");
            TimeUnit.SECONDS.sleep(1);
            String ans = "hello world";
            log.info("执行任务完毕, 返回结果 : {}", ans);
            return ans;
        });
        executorService.execute(futureTask);
        for (int i = 0; i < 4; i++) {
            new Thread(()->{
                try {
                    String res = futureTask.get();
                    log.info("拿到执行结果 : {}", res);
                } catch (InterruptedException | ExecutionException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }
        //00:31:49.690 [pool-1-thread-1] INFO com.hdu.Main - 开始执行任务.....
        //00:31:50.700 [pool-1-thread-1] INFO com.hdu.Main - 执行任务完毕, 返回结果 : hello world
        //00:31:50.701 [Thread-0] INFO com.hdu.Main - 拿到执行结果 : hello world
        //00:31:50.701 [Thread-3] INFO com.hdu.Main - 拿到执行结果 : hello world
        //00:31:50.701 [Thread-2] INFO com.hdu.Main - 拿到执行结果 : hello world
        //00:31:50.701 [Thread-1] INFO com.hdu.Main - 拿到执行结果 : hello world
    }

    public static void testEnhanceFutureTask2() throws InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        EnhanceFutureTask<String> enhanceTask = buildEnhanceTask(()->{
            TimeUnit.SECONDS.sleep(1);
            return "hello world";
        });
        executorService.execute(enhanceTask);
        //01:10:49.965 [pool-1-thread-1] INFO com.hdu.Main - 触发成功回调, 任务执行结果 : hello world
        //01:10:49.967 [pool-1-thread-1] INFO com.hdu.Main - 触发finally回调, 任务执行结果/异常 : hello world
    }

    public static void testEnhanceFutureTask() throws InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        EnhanceFutureTask<String> enhanceTask = buildEnhanceTask(()->{
            try {
                TimeUnit.SECONDS.sleep(15);
            }
            catch (InterruptedException e) {
                log.info("任务被取消了");
                throw e;
            }
            return "hello world";
        });
        executorService.execute(enhanceTask);
        TimeUnit.SECONDS.sleep(1);
        enhanceTask.cancel(true);
        //01:11:59.451 [pool-1-thread-1] INFO com.hdu.Main - 任务被取消了
        //01:11:59.451 [main] INFO com.hdu.Main - 任务被取消
        //01:11:59.452 [pool-1-thread-1] INFO com.hdu.Main - 触发失败回调, 任务执行异常 : sleep interrupted
        //01:11:59.453 [pool-1-thread-1] INFO com.hdu.Main - 触发finally回调, 任务执行结果/异常 : sleep interrupted
    }

    public static EnhanceFutureTask<String> buildEnhanceTask(Callable<String> callable) {
       return EnhanceFutureTask.of(callable)
                .addSuccessListener((task) -> log.info("触发成功回调, 任务执行结果 : {}" , task.getResult()))
                .addFinallyListener(
                        (task) -> log.info(
                                "触发finally回调, 任务执行结果/异常 : {}", task.getResult() != null
                                        ? task.getResult()
                                        : task.getException().getMessage()
                        )
                )
                .addFailureListener((task) -> log.info("触发失败回调, 任务执行异常 : {}", task.getException().getMessage()))
                .addCancelListener((task) ->  log.info("任务被取消"));
    }
}
